#pragma once

#include <algorithm/analytical_model/algorithm/cuda/inter_op/Data.h>
#include <algorithm/analytical_model/algorithm/cuda/inter_op/grid/Grid.h>

#include <vector>

namespace solar::cuda
{
    class RectangleGrid;
}

namespace solar::cuda::inter_op
{
    class RectangleHeliostat;
    class ShadowBlockCalculator;

    class RectangleGrid : public Grid
    {
        public:
            RectangleGrid();
            // Set *d_grid_helio_match_, *d_grid_helio_index_ and num_grid_helio_match_
            [[nodiscard]] auto
            gridHelioMatch(const std::vector<RectangleHeliostat>& heliostats) const
                -> int override;
            auto gridHelioMatchGPU(const std::vector<RectangleHeliostat>& heliostats) const -> void;
            void init() const override;
            void clear() const override;
            [[nodiscard]] auto getSubGridNum() const -> Int3;
            [[nodiscard]] auto getNumGridHelioMatch() const -> std::size_t;
            [[nodiscard]] auto getCudaStream() const -> cudaStream_t;

            friend class ShadowBlockCalculator;
    };
} // namespace solar::cuda::inter_op
